/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <gtest/gtest.h>
#include <cstring>
#include <cstdint>
#include <vector>

// 包含待测试的头文件
extern "C" {
#include <pldm/pldm_protocol.h>
#include <pldm/pldm_emulex.h>
}

namespace test_pldm {

// 测试宏定义的正确性
class pldm_macro_test : public ::testing::Test {
protected:
    void SetUp() override {}
    void TearDown() override {}
};

// 测试FW_VERSION_TLV_TYPE宏
TEST_F(pldm_macro_test, fw_version_tlv_type) {
    EXPECT_EQ(FW_VERSION_TLV_TYPE, 0x02);
}

// 测试PART_NUMBER_TLV_TYPE宏
TEST_F(pldm_macro_test, part_number_tlv_type) {
    EXPECT_EQ(PART_NUMBER_TLV_TYPE, 0x03);
}

// 测试SERIAL_NUMBER_TLV_TYPE宏
TEST_F(pldm_macro_test, serial_number_tlv_type) {
    EXPECT_EQ(SERIAL_NUMBER_TLV_TYPE, 0x04);
}

// 测试WWNN_TLV_TYPE宏
TEST_F(pldm_macro_test, wwnn_tlv_type) {
    EXPECT_EQ(WWNN_TLV_TYPE, 0x83);
}

// 测试WWPN_TLV_TYPE宏
TEST_F(pldm_macro_test, wwpn_tlv_type) {
    EXPECT_EQ(WWPN_TLV_TYPE, 0x84);
}

// 测试MAX_FRU_TABLE_RECORD_NUM宏
TEST_F(pldm_macro_test, max_fru_table_record_num) {
    EXPECT_EQ(MAX_FRU_TABLE_RECORD_NUM, 6);
}

// 测试FRU_RECORD_ID宏
TEST_F(pldm_macro_test, fru_record_id_general) {
    EXPECT_EQ(FRU_RECORD_ID_GENERAL, 1);
}

TEST_F(pldm_macro_test, fru_record_id_chip) {
    EXPECT_EQ(FRU_RECORD_ID_CHIP, 3);
}

TEST_F(pldm_macro_test, fru_record_id_port0) {
    EXPECT_EQ(FRU_RECORD_ID_PORT0, 4);
}

TEST_F(pldm_macro_test, fru_record_id_port1) {
    EXPECT_EQ(FRU_RECORD_ID_PORT1, 5);
}

// 测试MCTP_PLDM宏
TEST_F(pldm_macro_test, mctp_pldm_get_record_table_first_part) {
    EXPECT_EQ(MCTP_PLDM_GET_RECORD_TABLE_FIRST_PART, 0x01);
}

TEST_F(pldm_macro_test, mctp_pldm_get_record_table_next_part) {
    EXPECT_EQ(MCTP_PLDM_GET_RECORD_TABLE_NEXT_PART, 0x00);
}

TEST_F(pldm_macro_test, fru_table_transfer_flag_end) {
    EXPECT_EQ(FRU_TABLE_TRANSFER_FLAG_END, 0x04);
}

TEST_F(pldm_macro_test, fru_table_transfer_flag_start_end) {
    EXPECT_EQ(FRU_TABLE_TRANSFER_FLAG_START_END, 0x05);
}

// 测试MCTP_PLDM_TYPE宏
TEST_F(pldm_macro_test, mctp_pldm_type_2) {
    EXPECT_EQ(MCTP_PLDM_TYPE_2, 0x02);
}

TEST_F(pldm_macro_test, mctp_pldm_type_4) {
    EXPECT_EQ(MCTP_PLDM_TYPE_4, 0x04);
}

// 测试传感器相关宏
TEST_F(pldm_macro_test, mctp_pldm_sensor_operation_state_enable) {
    EXPECT_EQ(MCTP_PLDM_SENSOR_OPERATION_STATE_ENABLE, 0x00);
}

TEST_F(pldm_macro_test, mctp_emulex_sensor_state_connect) {
    EXPECT_EQ(MCTP_EMULEX_SENSOR_STATE_CONNECT, 0x01);
}

TEST_F(pldm_macro_test, pldm_get_sensor_reading) {
    EXPECT_EQ(PLDM_GET_SENSOR_READING, 0x11);
}

TEST_F(pldm_macro_test, pldm_get_state_sensor_readings) {
    EXPECT_EQ(PLDM_GET_STATE_SENSOR_READINGS, 0x21);
}

TEST_F(pldm_macro_test, mctp_pldm_cmd_get_record_table) {
    EXPECT_EQ(MCTP_PLDM_CMD_GET_RECORD_TABLE, 0x02);
}

// 测试结构体大小和对齐
class pldm_structure_test : public ::testing::Test {
protected:
    void SetUp() override {}
    void TearDown() override {}
};

// 测试pldm_get_fru_record_table_rsp_t结构体
TEST_F(pldm_structure_test, pldm_get_fru_record_table_rsp_size) {
    // 结构体应该按1字节对齐，包含：uint32_t + uint8_t + uint16_t + uint8_t + uint8_t + uint8_t + uint8_t[1]
    // 大小应该是：4 + 1 + 2 + 1 + 1 + 1 + 1 = 11字节
    EXPECT_EQ(sizeof(pldm_get_fru_record_table_rsp_t), 11);
}

// 测试pldm_get_fru_record_table_req_t结构体
TEST_F(pldm_structure_test, pldm_get_fru_record_table_req_size) {
    // 结构体应该按1字节对齐，包含：uint32_t + uint8_t
    // 大小应该是：4 + 1 = 5字节
    EXPECT_EQ(sizeof(pldm_get_fru_record_table_req_t), 5);
}

// 测试pldm_sensor_reading_rsp_t结构体
TEST_F(pldm_structure_test, pldm_sensor_reading_rsp_size) {
    // 结构体应该按1字节对齐，包含：6个uint8_t + uint8_t[1]
    // 大小应该是：6 + 1 = 7字节
    EXPECT_EQ(sizeof(pldm_sensor_reading_rsp_t), 7);
}

// 测试pldm_state_sensor_reading_rsp_t结构体
TEST_F(pldm_structure_test, pldm_state_sensor_reading_rsp_size) {
    // 结构体应该按1字节对齐，包含：uint8_t
    // 大小应该是：1字节
    EXPECT_EQ(sizeof(pldm_state_sensor_reading_rsp_t), 1);
}

// 测试pldm_statesensor_field_t结构体
TEST_F(pldm_structure_test, pldm_statesensor_field_size) {
    // 结构体应该按1字节对齐，包含：4个uint8_t
    // 大小应该是：4字节
    EXPECT_EQ(sizeof(pldm_statesensor_field_t), 4);
}

// 测试结构体成员偏移
TEST_F(pldm_structure_test, pldm_get_fru_record_table_rsp_offsets) {
    pldm_get_fru_record_table_rsp_t rsp;

    // 验证各字段的偏移量
    EXPECT_EQ((uintptr_t)&rsp.next_data_transfer_handle - (uintptr_t)&rsp, 0);
    EXPECT_EQ((uintptr_t)&rsp.transfer_flag - (uintptr_t)&rsp, 4);
    EXPECT_EQ((uintptr_t)&rsp.record_id - (uintptr_t)&rsp, 5);
    EXPECT_EQ((uintptr_t)&rsp.record_type - (uintptr_t)&rsp, 7);
    EXPECT_EQ((uintptr_t)&rsp.number_field - (uintptr_t)&rsp, 8);
    EXPECT_EQ((uintptr_t)&rsp.encoding_type - (uintptr_t)&rsp, 9);
    EXPECT_EQ((uintptr_t)&rsp.data - (uintptr_t)&rsp, 10);
}

// 测试结构体成员偏移
TEST_F(pldm_structure_test, pldm_get_fru_record_table_req_offsets) {
    pldm_get_fru_record_table_req_t req;

    // 验证各字段的偏移量
    EXPECT_EQ((uintptr_t)&req.data_transfer_handle - (uintptr_t)&req, 0);
    EXPECT_EQ((uintptr_t)&req.transfer_operation_flag - (uintptr_t)&req, 4);
}

// 测试传感器响应结构体成员偏移
TEST_F(pldm_structure_test, pldm_sensor_reading_rsp_offsets) {
    pldm_sensor_reading_rsp_t rsp;

    EXPECT_EQ((uintptr_t)&rsp.sensor_data_size - (uintptr_t)&rsp, 0);
    EXPECT_EQ((uintptr_t)&rsp.sensor_operational_state - (uintptr_t)&rsp, 1);
    EXPECT_EQ((uintptr_t)&rsp.event_message_enable - (uintptr_t)&rsp, 2);
    EXPECT_EQ((uintptr_t)&rsp.present_state - (uintptr_t)&rsp, 3);
    EXPECT_EQ((uintptr_t)&rsp.previous_state - (uintptr_t)&rsp, 4);
    EXPECT_EQ((uintptr_t)&rsp.event_state - (uintptr_t)&rsp, 5);
    EXPECT_EQ((uintptr_t)&rsp.sensor_data - (uintptr_t)&rsp, 6);
}

// 测试状态传感器响应结构体成员偏移
TEST_F(pldm_structure_test, pldm_state_sensor_reading_rsp_offsets) {
    pldm_state_sensor_reading_rsp_t rsp;

    EXPECT_EQ((uintptr_t)&rsp.composite_sensor_count - (uintptr_t)&rsp, 0);
}

// 测试状态传感器字段结构体成员偏移
TEST_F(pldm_structure_test, pldm_statesensor_field_offsets) {
    pldm_statesensor_field_t field;

    EXPECT_EQ((uintptr_t)&field.operational_state - (uintptr_t)&field, 0);
    EXPECT_EQ((uintptr_t)&field.present_state - (uintptr_t)&field, 1);
    EXPECT_EQ((uintptr_t)&field.previous_state - (uintptr_t)&field, 2);
    EXPECT_EQ((uintptr_t)&field.event_state - (uintptr_t)&field, 3);
}

// 测试字节序转换宏
class pldm_endianness_test : public ::testing::Test {
protected:
    void SetUp() override {}
    void TearDown() override {}
};

// 测试16位字节序转换
TEST_F(pldm_endianness_test, le16_conversion) {
    uint16_t test_value = 0x1234;
    uint16_t expected_le = 0x3412;  // 小端格式
    uint16_t expected_be = 0x1234;  // 大端格式

#ifdef BD_BIG_ENDIAN
    // 大端系统
    EXPECT_EQ(PLDM_LE16_TO_CPU(test_value), expected_le);
    EXPECT_EQ(PLDM_CPU_TO_LE16(test_value), expected_le);
    EXPECT_EQ(PLDM_BE16_TO_CPU(test_value), expected_be);
    EXPECT_EQ(PLDM_CPU_TO_BE16(test_value), expected_be);
#else
    // 小端系统
    EXPECT_EQ(PLDM_LE16_TO_CPU(test_value), expected_be);
    EXPECT_EQ(PLDM_CPU_TO_LE16(test_value), expected_be);
    EXPECT_EQ(PLDM_BE16_TO_CPU(test_value), expected_le);
    EXPECT_EQ(PLDM_CPU_TO_BE16(test_value), expected_le);
#endif
}

// 测试32位字节序转换
TEST_F(pldm_endianness_test, le32_conversion) {
    uint32_t test_value = 0x12345678;
    uint32_t expected_le = 0x78563412;  // 小端格式
    uint32_t expected_be = 0x12345678;  // 大端格式

#ifdef BD_BIG_ENDIAN
    // 大端系统
    EXPECT_EQ(PLDM_LE32_TO_CPU(test_value), expected_le);
    EXPECT_EQ(PLDM_CPU_TO_LE32(test_value), expected_le);
    EXPECT_EQ(PLDM_BE32_TO_CPU(test_value), expected_be);
    EXPECT_EQ(PLDM_CPU_TO_BE32(test_value), expected_be);
#else
    // 小端系统
    EXPECT_EQ(PLDM_LE32_TO_CPU(test_value), expected_be);
    EXPECT_EQ(PLDM_CPU_TO_LE32(test_value), expected_be);
    EXPECT_EQ(PLDM_BE32_TO_CPU(test_value), expected_le);
    EXPECT_EQ(PLDM_CPU_TO_BE32(test_value), expected_le);
#endif
}

// 测试字节序转换的逆操作
TEST_F(pldm_endianness_test, endianness_roundtrip) {
    uint16_t original16 = 0xABCD;
    uint32_t original32 = 0x12345678;

    // 16位转换的往返测试
    uint16_t le16 = PLDM_CPU_TO_LE16(original16);
    uint16_t back16 = PLDM_LE16_TO_CPU(le16);
    EXPECT_EQ(back16, original16);

    uint16_t be16 = PLDM_CPU_TO_BE16(original16);
    uint16_t back16_be = PLDM_BE16_TO_CPU(be16);
    EXPECT_EQ(back16_be, original16);

    // 32位转换的往返测试
    uint32_t le32 = PLDM_CPU_TO_LE32(original32);
    uint32_t back32 = PLDM_LE32_TO_CPU(le32);
    EXPECT_EQ(back32, original32);

    uint32_t be32 = PLDM_CPU_TO_BE32(original32);
    uint32_t back32_be = PLDM_BE32_TO_CPU(be32);
    EXPECT_EQ(back32_be, original32);
}

// 测试结构体序列化和反序列化
class pldm_serialization_test : public ::testing::Test {
protected:
    void SetUp() override {}
    void TearDown() override {}
};

// 测试pldm_get_fru_record_table_req_t的序列化
TEST_F(pldm_serialization_test, fru_record_table_req_serialization) {
    pldm_get_fru_record_table_req_t req;
    req.data_transfer_handle = 0x12345678;
    req.transfer_operation_flag = 0xAB;

    // 序列化到缓冲区
    std::vector<uint8_t> buffer(sizeof(pldm_get_fru_record_table_req_t));
    std::memcpy(buffer.data(), &req, sizeof(req));

    // 验证序列化结果
    EXPECT_EQ(buffer[0], 0x78);  // 小端格式的低字节
    EXPECT_EQ(buffer[1], 0x56);
    EXPECT_EQ(buffer[2], 0x34);
    EXPECT_EQ(buffer[3], 0x12);  // 小端格式的高字节
    EXPECT_EQ(buffer[4], 0xAB);

    // 反序列化
    pldm_get_fru_record_table_req_t req2;
    std::memcpy(&req2, buffer.data(), sizeof(req2));

    EXPECT_EQ(req2.data_transfer_handle, req.data_transfer_handle);
    EXPECT_EQ(req2.transfer_operation_flag, req.transfer_operation_flag);
}

// 测试pldm_sensor_reading_rsp_t的序列化
TEST_F(pldm_serialization_test, sensor_reading_rsp_serialization) {
    pldm_sensor_reading_rsp_t rsp;
    rsp.sensor_data_size = 4;
    rsp.sensor_operational_state = 1;
    rsp.event_message_enable = 1;
    rsp.present_state = 2;
    rsp.previous_state = 1;
    rsp.event_state = 0;
    rsp.sensor_data[0] = 0x11;

    // 序列化到缓冲区
    std::vector<uint8_t> buffer(sizeof(pldm_sensor_reading_rsp_t));
    std::memcpy(buffer.data(), &rsp, sizeof(rsp));

    // 验证序列化结果
    EXPECT_EQ(buffer[0], 4);   // sensor_data_size
    EXPECT_EQ(buffer[1], 1);   // sensor_operational_state
    EXPECT_EQ(buffer[2], 1);   // event_message_enable
    EXPECT_EQ(buffer[3], 2);   // present_state
    EXPECT_EQ(buffer[4], 1);   // previous_state
    EXPECT_EQ(buffer[5], 0);   // event_state
    EXPECT_EQ(buffer[6], 0x11); // sensor_data[0]

    // 反序列化
    pldm_sensor_reading_rsp_t rsp2;
    std::memcpy(&rsp2, buffer.data(), sizeof(rsp2));

    EXPECT_EQ(rsp2.sensor_data_size, rsp.sensor_data_size);
    EXPECT_EQ(rsp2.sensor_operational_state, rsp.sensor_operational_state);
    EXPECT_EQ(rsp2.event_message_enable, rsp.event_message_enable);
    EXPECT_EQ(rsp2.present_state, rsp.present_state);
    EXPECT_EQ(rsp2.previous_state, rsp.previous_state);
    EXPECT_EQ(rsp2.event_state, rsp.event_state);
    EXPECT_EQ(rsp2.sensor_data[0], rsp.sensor_data[0]);
}

// 测试边界条件
class pldm_boundary_test : public ::testing::Test {
protected:
    void SetUp() override {}
    void TearDown() override {}
};

// 测试最大值边界
TEST_F(pldm_boundary_test, max_values) {
    pldm_get_fru_record_table_rsp_t rsp;
    rsp.next_data_transfer_handle = UINT32_MAX;
    rsp.transfer_flag = UINT8_MAX;
    rsp.record_id = UINT16_MAX;
    rsp.record_type = UINT8_MAX;
    rsp.number_field = UINT8_MAX;
    rsp.encoding_type = UINT8_MAX;
    rsp.data[0] = UINT8_MAX;

    // 验证可以处理最大值
    EXPECT_EQ(rsp.next_data_transfer_handle, UINT32_MAX);
    EXPECT_EQ(rsp.transfer_flag, UINT8_MAX);
    EXPECT_EQ(rsp.record_id, UINT16_MAX);
    EXPECT_EQ(rsp.record_type, UINT8_MAX);
    EXPECT_EQ(rsp.number_field, UINT8_MAX);
    EXPECT_EQ(rsp.encoding_type, UINT8_MAX);
    EXPECT_EQ(rsp.data[0], UINT8_MAX);
}

// 测试最小值边界
TEST_F(pldm_boundary_test, min_values) {
    pldm_get_fru_record_table_rsp_t rsp = {0};
    rsp.next_data_transfer_handle = 0;
    rsp.transfer_flag = 0;
    rsp.record_id = 0;
    rsp.record_type = 0;
    rsp.number_field = 0;
    rsp.encoding_type = 0;
    rsp.data[0] = 0;

    // 验证可以处理最小值
    EXPECT_EQ(rsp.next_data_transfer_handle, 0U);
    EXPECT_EQ(rsp.transfer_flag, 0);
    EXPECT_EQ(rsp.record_id, 0);
    EXPECT_EQ(rsp.record_type, 0);
    EXPECT_EQ(rsp.number_field, 0);
    EXPECT_EQ(rsp.encoding_type, 0);
    EXPECT_EQ(rsp.data[0], 0);
}

} // namespace test_pldm
